package com.sumainfor.pc.market.service;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.netflix.discovery.converters.Auto;
import com.sumainfor.common.NiuYunToken;
import com.sumainfor.common.UnionPay.MapUtil;
import com.sumainfor.common.config.LockUtil;
import com.sumainfor.common.exception.TCException;
import com.sumainfor.common.util.*;
import com.sumainfor.common.utlis.ParamsCommon;
import com.sumainfor.pc.market.dao.EnterPriseManageMapper;
import com.sumainfor.pc.market.feign.BaseFeignGmio;
import com.sumainfor.pc.market.feign.TenantFeign;
import com.sumainfor.pc.market.feign.Zfeign.ZzuulFeign;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.collections.MapUtils;
import org.joda.time.DateTime;
import org.joda.time.Months;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.Month;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @Author Eddy·Chen
 * @Email 835033913@qq.com
 * @Create 2019-06-03 15:04
 */
@Service
@Transactional(rollbackFor = Exception.class)
@Log4j2
public class EnterPriseManageService {

    @Autowired
    private EnterPriseManageMapper mapper;

    @Autowired
    private LockUtil lockUtil;

    @Autowired
    private TenantFeign tenantFeign;

    @Autowired
    private BaseFeignGmio gmio;

    @Autowired
    private ZzuulFeign zuul;

    /**
     * 查询主页所有的企业列表
     *
     * @return
     */
    public JsonResult selectMainTableList() {
        List<Map<String, Object>> corporateList = mapper.selectCorporateList();
        //查询房间剩余个数
        for (Map<String, Object> map : corporateList) {
            //所有的房源
            List<Map<String, Object>> hList = mapper.selectHousingForCorId(MapUtils.getString(map, "CorId"));
            map.put("HousingAllCount", hList.size());
            //已入住的
            map.put("HousingDoneCount", hList.stream().filter(stringObjectMap -> MapUtils.getInteger(stringObjectMap, "Status").equals(1)).count());
            List<Map<String, Object>> user = mapper.selectUserForCorId(CustomMap.create("CorId", MapUtils.getString(map, "CorId")));
            //所有的成员个数
            map.put("UserAllCount", user.size());
        }
        return JsonResult.success(corporateList);
    }

    /**
     * 查询企业房源入住情况 表格数据
     *
     * @param corId
     * @return
     */
    public JsonResult selectHousingTable(Page page, String corId) {
        IPage<Map<String, Object>> list = mapper.selectHousingStateList(page, corId);
        return JsonResult.success(list);
    }


    /**
     * 搜索员工
     *
     * @param phone
     * @param corId
     * @param housingId
     * @return
     */
    public JsonResult queryUserForPhone(String phone, String corId, String housingId) {
        //查询用户信息
        JsonResult<Map<String, Object>> tenantJson = tenantFeign.getTenantByPhone(phone);
        if (!tenantJson.isSuccess()) {
            return tenantJson;
        }
        Map<String, Object> tenantMap = tenantJson.getResult();
        //URl  前缀
        tenantMap.put("UrlPrefix", NiuYunToken.publicQiniuUrl);

        CustomMap data = CustomMap.create("Tenant", tenantMap);
        //查询是否承担费用
        Map<String, Object> corporate = mapper.getCorporateByCorId(corId);
        if (MapUtils.isEmpty(corporate)) {
            return JsonResult.error("不存在的企业客户");
        }
        //查询收费标准数据
        Map<String, Object> rates = this.getRates(housingId);
        //1.公共事业费
        data.put("IfCost", MapUtils.getInteger(corporate, "IfCost").equals(0));
        //2.房租
        data.put("IfRent", MapUtils.getInteger(corporate, "IfRent").equals(0));
        data.put("ConstMoney", mapper.getHousingMoney(housingId));
        //3.房租押金
        data.put("IfRentDeposit", MapUtils.getInteger(corporate, "IfRentDeposit").equals(0));
        data.put("RentDepositMoney", data.get("ConstMoney"));
        //4.水电然押金
        data.put("IfCostDeposit", MapUtils.getInteger(corporate, "IfCostDeposit").equals(0));
        data.put("CostDepositMoney", rates.get("WaDeposit"));
        //5.其他费用押金
        data.put("IfAverage", MapUtils.getInteger(corporate, "IfAverage").equals(0));


        return JsonResult.success(data);
    }

    /**
     * 确认入住操作
     *
     * @param params
     * @return
     */
    public JsonResult confirmCheckIn(Map<String, Object> params) {
        try {
            if (lockUtil.getUntilHaveLock(getClass().getName())) {
                //租客编号
                String tenId = MapUtils.getString(params, "TenId");
                String corId = MapUtils.getString(params, "CorId");
                String houId = MapUtils.getString(params, "HouId");
                String infoId = MapUtils.getString(params, "HouInfoId");

                //检查是否被入住了
                Map<String, Object> chInfo = mapper.getCorporateHousingByParams(CustomMap.create("CorId", corId)
                        .put("HouId", houId)
                        .put("HouInfoId", infoId));
                if (MapUtils.getInteger(chInfo, "Status").equals(1)) {
                    return JsonResult.error("该房源已被入住");
                }

                //查询租客
                JsonResult<JSONObject> wxInfo = tenantFeign.getWxInfoByTenId(tenId);
                if (!wxInfo.isSuccess()) {
                    return JsonResult.error("找不到此租客");
                }
                JSONObject tenantInfo = wxInfo.getResult().getJSONObject("result");


                //查询企业主表数据
                Map<String, Object> mainInfo = mapper.getCorporateByCorId(corId);

                //查询房租
                String housingMoney = mapper.getHousingMoney(infoId);
                //查询收费标准数据
                Map<String, Object> rates = this.getRates(infoId);

                //构建企业客户数据
                CustomMap tenantData = CustomMap.create("CorMemId", UUIDUtils.generatePrefixUuid("CUSER"))
                        .put("CorId", corId)
                        .put("TenId", tenId)
                        .put("HouId", houId)
                        .put("HouInfoId", infoId)
                        .put("SigningTime", new Date())
                        .put("RentDeposit", housingMoney)
                        .put("CostDeposit", rates.get("WaDeposit"))
                        .put("Status", 1);
                //判断是否是企业承担公共事业费用
                if (Objects.equals(MapUtils.getInteger(mainInfo, "IfCost"), 1)) {
                    //企业不承担费用
                    if (!FieldCheckUtil.isMapFieldNotNull(params, "MonthEleSum", "MonthElePeak", "MonthEleFlat", "CheckHousing", "CheckGasSum", "CheckWaterSum")) {
                        return JsonResult.errorForEmpty();
                    }
                    tenantData.put("MonthEleSum", params.get("MonthEleSum"));
                    tenantData.put("MonthElePeak", params.get("MonthElePeak"));
                    tenantData.put("MonthEleFlat", params.get("MonthEleFlat"));
                    tenantData.put("CheckHousing", JSONObject.toJSONString(params.get("MonthEleFlat")));
                    tenantData.put("CheckGasSum", params.get("CheckGasSum"));
                    tenantData.put("CheckWaterSum", params.get("CheckWaterSum"));
                }
                ParamsCommon.commonInsertParms(tenantData, getClass());
                //插入数据到 企业成员表
                int row = mapper.insertTenant(tenantData);
                if (row <= 0) {
                    throw new TCException("创建企业客户失败");
                }
                //修改企业房源状态
                row = mapper.updateCorporateHousing(ParamsCommon.commonUpdateParms(CustomMap.create()
                                .put("CorId", corId)
                                .put("HouId", houId)
                                .put("HouInfoId", infoId)
                                .put("CorMemId", tenantData.get("CorMemId"))
                                .put("Status", 1)
                        , getClass()));
                if (row <= 0) {
                    throw new TCException("更新企业房源失败");
                }
                //插入日志记录
                row = mapper.insertCheckInLog(ParamsCommon.commonInsertParms(CustomMap.create()
                                .put("CorId", corId)
                                .put("HouId", houId)
                                .put("HouInfoId", infoId)
                                .put("CorMemId", tenantData.get("CorMemId"))
                                .put("Status", 0)
                                .put("Operate", new Date())
                                .put("TenantName", tenantInfo.getString("realName"))
                                .put("TenantPhone", tenantInfo.getString("tenPhone"))
                        , getClass()));
                if (row <= 0) {
                    throw new TCException("插入日志失败");
                }
                //判断是否需要生成租客应付账单首次的
                Map<String, Object> corporate = mapper.getCorporateByCorId(corId);
                //账单归属公司
                String areaId = mapper.getCorId(infoId);

                //生成房租金额 + 押金
                BigDecimal houMoney = new BigDecimal(housingMoney).multiply(new BigDecimal(MapUtils.getString(corporate, "Cormonth")));
                DateTime now = DateTime.now();
                DateTime plusMonths = now.plusMonths(MapUtils.getIntValue(corporate, "Cormonth"));
                int dayOfMonth = now.getDayOfMonth();
                DateTime lastTime;
                if (dayOfMonth > MapUtils.getIntValue(corporate, "Corday")) {
                    lastTime = now.plusMonths(1).withDayOfMonth(MapUtils.getIntValue(corporate, "Corday"));
                } else {
                    lastTime = now.withDayOfMonth(MapUtils.getIntValue(corporate, "Corday"));
                }

                CustomMap mainOrder = CustomMap.create("CorId", areaId)
                        .put("MainBody", 1)
                        .put("CorsId", areaId)
                        .put("Bibear", MapUtils.getInteger(corporate, "IfRent").equals(0) ? 0 : 1)
                        .put("BiName", "企业第一次房租账单")
                        .put("IfTemporary", 1)
                        .put("BiType", 1)
                        .put("Source", tenantData.get("CorMemId"))
                        .put("DepositType", 1)
                        .put("FirstMon", 1)
                        .put("BiMoney", houMoney.add(new BigDecimal(housingMoney)))
                        .put("BillExplain", String.format("房租:%s,房租押金:%s", houMoney.toString(), housingMoney))
                        .put("BiGenerated", System.currentTimeMillis())
                        .put("EndTime", plusMonths.toDate().getTime())
                        .put("LateDay", lastTime.toDate().getTime())
                        .put("TenId", MapUtils.getInteger(corporate, "IfRent").equals(0) ? null : tenId)
                        .put("HouId", houId)
                        .put("HouInfoId", infoId)
                        .put("CreateType", 2)
                        .put("Create", ContextUtils.getUserId())
                        .put("Status", 1)
                        .put("Abnormal", 0);
                JsonResult orderMain = gmio.createOrderMain(mainOrder);
                if (!orderMain.isSuccess()) {
                    throw new TCException(orderMain.getErrorMessage());
                }

                //生成临时账单
                CustomMap tempOrder = CustomMap.create("CorId", areaId)
                        .put("TemType", 2)
                        .put("SourceId", orderMain.getResult())
                        .put("HouId", houId)
                        .put("HouInfoId", infoId)
                        .put("TenType", MapUtils.getInteger(corporate, "IfRent").equals(0) ? null : 2)
                        .put("TenId", MapUtils.getInteger(corporate, "IfRent").equals(0) ? null : tenId)
                        .put("Cost", housingMoney)
                        .put("Remark", "企业租客房租押金账单")
                        .put("SysUserId", ContextUtils.getUserId())
                        .put("Status", 1);
                JsonResult temoOrder = gmio.createTempOrder(tempOrder);
                if (!temoOrder.isSuccess()) {
                    throw new TCException(temoOrder.getErrorMessage());
                }

                //创建 水电燃押金账单
                CustomMap depositOrder = CustomMap.create("CorId", areaId)
                        .put("MainBody", 1)
                        .put("CorsId", areaId)
                        .put("Bibear", MapUtils.getInteger(corporate, "IfRent").equals(0) ? 0 : 1)
                        .put("BiName", "企业第一次水电燃押金账单")
                        .put("IfTemporary", 0)
                        .put("BiType", 1)
                        .put("Source", tenantData.get("CorMemId"))
                        .put("DepositType", 2)
                        .put("FirstMon", 1)
                        .put("BiMoney", rates.get("WaDeposit"))
                        .put("BillExplain", String.format("水电押金:%s", rates.get("WaDeposit")))
                        .put("BiGenerated", System.currentTimeMillis())
                        .put("EndTime", plusMonths.toDate().getTime())
                        .put("LateDay", lastTime.toDate().getTime())
                        .put("TenId", MapUtils.getInteger(corporate, "IfRent").equals(0) ? null : tenId)
                        .put("HouId", houId)
                        .put("HouInfoId", infoId)
                        .put("CreateType", 2)
                        .put("Create", ContextUtils.getUserId())
                        .put("Status", 1)
                        .put("Abnormal", 0);

                JsonResult depositResult = gmio.createOrderMain(depositOrder);
                if (!depositResult.isSuccess()) {
                    throw new TCException(depositResult.getErrorMessage());
                }

                // TODO: 2019/6/4 待定
              /*  //判断企业不承担费用的时候
                if (Objects.equals(MapUtils.getInteger(mainInfo, "IfCost"), 1)) {
                    //1. 生成电费抄表记录和生成账单
                    //1.1 查询企业所包下的房源详表
                    List<Map<String, Object>> qyHouList = mapper.selectQyNotActivateHousing(corId, houId);
                    //1.2 查询房源详表中 已入住的房源
                    List<Map<String, Object>> otherHouList = mapper.selectHousingIdAndTenantId(houId, qyHouList.stream().map(qyHouItem -> MapUtils.getString(qyHouItem, "HouInfoId")).collect(Collectors.toList()));
                    otherHouList.addAll(qyHouList);
                    log.info("查询出来的需要平摊的租客和房源数据======> {} ",otherHouList);

                }*/

                return JsonResult.actionSuccess();
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lockUtil.unLock(getClass().getName());
            log.info(">-------释放锁资源-------<");
        }
        return JsonResult.error("系统遇到未知异常");
    }


    /**
     * 模糊查询 获得历史入住记录
     *
     * @param page
     * @param username
     * @param phone
     * @return
     */
    public JsonResult selectHistoryLog(Page page, String username, String phone) {
        IPage<Map<String, Object>> list = mapper.selectHistoryList(page, CustomMap.create("username", username).put("phone", phone));
        for (Map<String, Object> map : list.getRecords()) {
            DateUtils.formatDateByMap(map);
        }
        return JsonResult.success(list);
    }


    ///////////////////////////////////////////////////////////////////////////
    // 收费标准
    ///////////////////////////////////////////////////////////////////////////


    /**
     * 获取收费标准 根据房源详表编号查询
     *
     * @param infoId
     * @return
     */
    public Map<String, Object> getRates(String infoId) {
        //1. 先细分房源查询
        JsonResult<Map<String, Object>> result = gmio.selectRates(CustomMap.create("ContactId", infoId).put("ChaType", 5));
        if (!result.isSuccess()) {
            throw new TCException(result.getErrorMessage());
        }
        Map<String, Object> rates = result.getResult();
        if (MapUtils.isNotEmpty(rates)) {
            return rates;
        }
        //2. 查项目
        Map<String, Object> infoMap = mapper.getProjectInfoByInfoId(infoId);
        if (MapUtils.isEmpty(infoMap)) {
            return JsonResult.error("不存在的房源");
        }
        result = gmio.selectRates(CustomMap.create("ContactId", infoMap.get("ComId")).put("ChaType", 4));
        if (!result.isSuccess()) {
            throw new TCException(result.getErrorMessage());
        }
        rates = result.getResult();
        if (MapUtils.isNotEmpty(rates)) {
            return rates;
        }
        //3. 查服务中心
        result = gmio.selectRates(CustomMap.create("ContactId", infoMap.get("MiId")).put("ChaType", 3));
        if (!result.isSuccess()) {
            throw new TCException(result.getErrorMessage());
        }
        rates = result.getResult();
        if (MapUtils.isNotEmpty(rates)) {
            return rates;
        }
        //3. 查公司
        // 获取所属公司编号
        JsonResult gsJson = zuul.getAreaInfoForGSByDeptId(MapUtils.getString(infoMap, "MiId"));
        if (gsJson.isSuccess() == false) {
            throw new TCException("查询所属公司失败");
        }
        //公司编号
        Object areaId = gsJson.getResult();
        result = gmio.selectRates(CustomMap.create("ContactId", areaId).put("ChaType", 1));
        if (!result.isSuccess()) {
            throw new TCException(result.getErrorMessage());
        }
        rates = result.getResult();
        if (MapUtils.isNotEmpty(rates)) {
            return rates;
        }
        throw new TCException("该房源没有配置收费标准");
    }


}
